package cn.chen.proxy;

import cn.chen.proxy.compiler.InvocationHander;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

public class Proxy {

    /**
     * 产生新的代理类
     * @return
     */
    public static Object newProxyInstance(Class infce, InvocationHander h) throws Exception {
        String methodStr = "";
        String rt = "\n";
        Method[] methods = infce.getMethods();

//        for(Method method : methods){
//            methodStr += "@Override" + rt +
//                    "public void " + method.getName() + "()" +"{"+rt +
//                    "        long start = System.currentTimeMillis();" + rt +
//                    "        System.out.println(\"开始：\" + start);" + rt +
//                    "        tank."+method.getName()+"();\n" +
//                    "        long end = System.currentTimeMillis();\n" +
//                    "        System.out.println(\"运行：\" + (start - end));\n" +
//                    "}";
//        }

        for(Method method : methods){
            methodStr += "@Override" + rt +
                    "public void " + method.getName() + "()" +"{"+rt +
                        "   try{" + rt +
                        "   Method method = "+ infce.getName() + ".class.getMethod(\""+ method.getName()+"\");" + rt +
                        "   h.invoke(this,method);" + rt +
                        "   }catch(Exception e){e.printStackTrace();}" +
                    "}";
        }


        String src = "package cn.chen.proxy.compiler;\n" +
                "import cn.chen.proxy.Moveable;\n" +
                "import java.lang.reflect.Method;\n" +
                "public class $Proxy1 implements " + infce.getName() +" {\n" +

                "    public $Proxy1(InvocationHander h) {\n" +
                "        this.h = h;" + rt +
                "    }" + rt +

                "   cn.chen.proxy.compiler.InvocationHander h;"+ rt+
                        methodStr + rt+
                "}";
        // /Users/chenxiaokang/Documents/IDEAProject/mianshi
//        System.out.println(System.getProperty("user.dir"));
        String fileName = System.getProperty("user.dir") + "/src/main/java/cn/chen/proxy/compiler/$Proxy1.java";
        File f = new File(fileName);
        FileWriter fw = new FileWriter(f);
        fw.write(src);
        fw.flush();
        fw.close();
    // 编译
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        // com.sun.tools.javac.api.JavacTool
        //        System.out.println(compiler.getClass().getName());
        StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null,null,null);
        Iterable units = fileMgr.getJavaFileObjects(fileName);
        JavaCompiler.CompilationTask task = compiler.getTask(null, fileMgr, null, null, null,units);
        task.call();
        fileMgr.close();

        //load into memory and create an instance
        URL[] urls = new URL[]{new URL("file:/" + System.getProperty("user.dir") + "/src/main/java")};
        URLClassLoader ul = new URLClassLoader(urls);
        Class c = ul.loadClass("cn.chen.proxy.compiler.$Proxy1");
        System.out.println(c);

        Constructor constructor = c.getConstructor(InvocationHander.class);
        Object m = constructor.newInstance(h);
        return m;
    }

}
